import {
  Component,
  ViewEncapsulation,
  ChangeDetectionStrategy,
  Input,
  TemplateRef,
  ElementRef,
  ChangeDetectorRef,
  forwardRef,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { InputBoolean, TypeUtils } from '../core/api';
import { LvConfig } from '../core/config';
@Component({
  selector: 'lv-switch, [lv-switch]',
  exportAs: 'lvSwitch',
  templateUrl: './switch.component.html',
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef((): typeof SwitchComponent => SwitchComponent),
      multi: true,
    },
  ],
  host: {
    class: 'lv-switch-host',
    '[class.lv-switch-large]': "lvSize === 'large'",
  },
})
export class SwitchComponent implements ControlValueAccessor {
  @Input() @InputBoolean() lvLoading = false;

  @Input() @InputBoolean() lvControl = false;

  @Input() @InputBoolean() lvDisabled = false;

  @Input() lvLabelOn: string | TemplateRef<void>;

  @Input() lvLabelOff: string | TemplateRef<void>;

  @Input() lvSize: 'large' | 'default' = 'default';

  public typeUtils = TypeUtils;
  public checked: boolean = false;
  public assetsPrefixPath = LvConfig.assetsPrefixPath;
  constructor(
    public cdr: ChangeDetectorRef,
    private el: ElementRef,
  ) {}

  // 解决disabled状态下，不触发自定的click事件，讲_click挂载到switch组件的子元素上，才能通过阻止事件冒泡阻止自定义click事件
  registerOnChange(fn: any): void {
    this._onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this._onTouch = fn;
  }

  swithChange(): void {
    this.checked = !coerceBooleanProperty(this.checked);
    this._onChange(this.checked);
  }

  writeValue(value: boolean): void {
    this.checked = coerceBooleanProperty(value);
    this.cdr.markForCheck();
  }

  // 同等级的事件之间无法相互阻止
  _click(e: MouseEvent): void {
    if (this.lvDisabled || this.lvLoading) {
      e.stopPropagation();
      e.preventDefault();
      return;
    }

    if (!this.lvControl) {
      this.swithChange();
    }
  }

  private _onTouch: any = (): void => {};

  private _onChange: any = (): void => {};
}
